/*
 * @Description: 封装socket方法
 * @version:
 * @Date: 2022-11-17
 * @LastEditTime: 2022-11-17
 */
import { storeToRefs } from 'pinia'
import { msgTip } from '@/hooks/useMsgTip.js'

import useUIStore from '@/stores/UI.js'
import { useSimpleUIStore } from '@/stores/simpleTaskUI.js'
import { useSimpleTaskData } from '@/stores/simpleTaskData.js'
import { useMultipleUIStore } from '@/stores/multipleTaskUI.js'
import { useMultipleTaskData } from '@/stores/multipleTaskData.js'

const uiStore = useUIStore()
const { isSimpleTask } = storeToRefs(uiStore)

const simpleUIStore = useSimpleUIStore()
const { onSimpleTaskCompleteUI, UIOnSimpleSubmit } = simpleUIStore

const simpleTaskData = useSimpleTaskData()
const { initDataOnError } = simpleTaskData

const multipleUIStore = useMultipleUIStore()
const { onMultipleError, UIOnMultipleSubmit } = multipleUIStore

const multipleTaskData = useMultipleTaskData()
const { clearAllData, initMultipleTableData } = multipleTaskData

const socket = {
  websocket: null,
  connectURL: 'ws://localhost:8081/websocket/11',
  // 开启标识
  socket_open: false,
  // 心跳timer
  heartbeat_timer: null,
  // 心跳发送频率
  heartbeat_interval: 45000,
  // 是否自动重连
  is_reconnect: true,
  // 重连次数
  reconnect_count: 0,
  // 已发起重连次数
  reconnect_current: 0,
  // 网络错误提示此时
  reconnect_number: 0,
  // 重连timer
  reconnect_timer: null,
  // 重连频率
  reconnect_interval: 5000,
  // 收到信息的处理回调
  receiveMessage: null,

  init: (receiveMessage) => new Promise((resolve, reject) => {
    socket.receiveMessage = receiveMessage
    if (!('WebSocket' in window)) {
      ElMessage.warning('浏览器不支持WebSocket')
      return null
    }

    socket.websocket = new WebSocket(socket.connectURL)

    socket.websocket.onmessage = (event) => {
      if (receiveMessage) {
        receiveMessage(event.data)
      }
    }

    socket.websocket.onclose = (e) => {
      socket.restorePage()
      socket.heartbeat_timer && clearInterval(socket.heartbeat_timer)
      socket.socket_open = false
      // 需要重新连接
      if (socket.is_reconnect) {
        socket.reconnect_timer = setTimeout(() => {
          // 超过重连次数
          if (socket.reconnect_current >= socket.reconnect_count) {
            clearTimeout(socket.reconnect_timer)
            socket.is_reconnect = false
            msgTip('Info', 'socket has been closed', 'info')
            return
          }
          // 记录重连次数
          socket.reconnect_current++
          msgTip('Warning', `Attempting the ${socket.reconnect_current}th reconnection`, 'warning')
          socket.reconnect(receiveMessage, null)
        }, socket.reconnect_interval)
      }
    }

    // 连接成功
    socket.websocket.onopen = function() {
      socket.reconnect_current = 0
      socket.socket_open = true
      // 自动重新连接
      socket.is_reconnect = true
      // 开启心跳
      // socket.heartbeat()
      msgTip('Success', 'Socket initialization successful', 'success')
      resolve()
    }

    // 连接发生错误
    socket.websocket.onerror = function(e) {
      msgTip('Error', 'Websocket connection error', 'error')
      reject(null)
    }
  }),

  send: (data) => {
    if (!(socket.websocket.readyState === socket.websocket.OPEN)) {
      socket.reconnect(socket.receiveMessage, data)
      return
    }
    socket.websocket.send(JSON.stringify(data))
    msgTip('Success', 'Task submitted successfully', 'success')
  },

  receive: (message) => {
    return message
  },
  // 心跳检测,目前没啥用
  heartbeat: () => {
    socket.heartbeat_timer && clearInterval(socket.heartbeat_timer)
    socket.heartbeat_timer = setInterval(() => {
      let data = {
        /* languageId: store.state.users.language,
         authToken: store.state.users.authorization,*/
        content: 'ping'
      }
      let sendData = {
        // encryption_type: 'base64',
        // data: Base64.encode(JSON.stringify(data)),
        data
      }
      socket.send(sendData)
    }, socket.heartbeat_interval)
  },

  close: () => {
    socket.heartbeat_timer && clearInterval(socket.heartbeat_timer)
    socket.is_reconnect = false
    socket.websocket.close()
  },

  /**
   * 重新连接
   */
  reconnect: (receiveMessage, data) => {
    socket.init(receiveMessage).then(() => {
      data != null && socket.send(data)
    })
  },

  restorePage: () => {
    initDataOnError()
    onSimpleTaskCompleteUI()
    clearAllData()
    onMultipleError()
  }
}

export default socket

